/**
 * 文件名    ： CrawTextThread.java
 * 版权       : XX科技有限公司。
 * 描述       : <描述>
 * 修改时间：2018年11月11日
 * 修改内容：<修改内容>
 */
package com.example.demo.application.crawutil.novel;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.example.demo.application.common.base.IBaseService;
import com.example.demo.application.model.NovelCrawEntity;
import com.example.demo.application.service.INovelService;

/**
 * 小说爬虫 线程 <一句话功能简述> <功能详细描述>
 * 
 * @author 87431
 * @version [版本号，2018年11月11日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class NovelCrawTextThread extends Thread {

	protected static final Logger log = LoggerFactory.getLogger(NovelCrawTextThread.class);

	private NovelCrawEntity entity;

	String rule_title = "h1";
	String rule_content = "content";

	private static IBaseService<NovelCrawEntity, Serializable> service;

	public NovelCrawTextThread(NovelCrawEntity data, IBaseService<NovelCrawEntity, Serializable> service) {
		this.entity = data;
		this.service = service;
	}

	// Jsoup  或者 
	@Override
	public void run() {
		currentThread().setName(entity.getTitle());
		////2：防爬虫，反动态js技术
		if("2".equals(entity.getDownloadType())) {
			
			return;
		}
		String title = "";
		String content = "";
		// 章节列表
		List<String> urlList = new ArrayList<String>();
		String rule = "abs:href";
		rule = this.entity.getRule();

		String Url = this.entity.getDestUrl();
		Document document = null;
		try {
			Connection conn = Jsoup.connect(Url).timeout(60000).ignoreContentType(true)
					.userAgent("Mozilla\" to \"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0)");
//			        .userAgent(this.entity.getUserAgent())
//			        .get();
			conn.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
			conn.header("Accept-Encoding", "gzip, deflate");
			conn.header("Accept-Language", "zh-CN,zh;q=0.9");
			conn.header("Connection", "keep-alive");
			conn.header("Host", "www.biquge.com.tw");
			conn.header("Upgrade-Insecure-Requests", "1");
			conn.header("If-None-Match", "\"208693f45774d41:0\"");
			conn.header("If-Modified-Since", "Sun, 04 Nov 2018 16:03:41 GMT");
			conn.header("Referer", Url);
//			conn.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36");
			document = conn.get();

//	        log.info(document.toString());
//	        Elements urlNode = document.select("a[href$=.html]");
			Elements urlNode = document.select(this.entity.getUrlNodeTemplet());
			for (Element element : urlNode) {
				urlList.add(element.attr(rule));
			}
			log.error("url数量：  " + urlList.size());
		} catch (IOException e1) {
			log.error("线程:" + currentThread().getName() + "  " + e1.getMessage());
			/// 失败
			entity.setStatus("-1");
			entity.setRemark("Jsoup.connect   document.select ");
			entity.setLastTime(new Date());
			try {
				service.update(entity);
			} catch (Exception e) {
				log.error("小说爬虫线程异常  " + e1.getMessage());
			}
			return;
		}
		String PATH = "";
		PATH = entity.getFilePath();
		File file_tmp = new File(PATH);
		try {
			if (!file_tmp.exists()) {
				/// 未下载
				entity.setStatus("-1");
				entity.setLastTime(new Date());
				entity.setRemark("PATH not exists");
				service.update(entity);
				file_tmp = null;
				return;
			} else {
				PATH = file_tmp.getCanonicalPath() + "/";
				/// 正在下载
				entity.setStatus("3");
				entity.setLastTime(new Date());
			}
			service.update(entity);
		} catch (Exception e1) {
			log.error("小说爬虫线程异常  " + e1.getMessage());
			return;
		}
		StringBuilder msg= new StringBuilder();
		try {
			int i =0;
			boolean isStart = true;
			if(StringUtils.isNotBlank(entity.getLastUrl())) {
				isStart = false;
			}
			for (String url : urlList) {
				if(!isStart)
				{
					if(url.equals(entity.getLastUrl())) {
						isStart = true;
					}else {
						continue;
					}
				}
				//下载
				downLoad(msg, url, entity, PATH);
				downLoad(msg, url.split(".html")[0]+"_2.html", entity, PATH);
				downLoad(msg, url.split(".html")[0]+"_3.html", entity, PATH);
				downLoad(msg, url.split(".html")[0]+"_4.html", entity, PATH);
				i++;
				if(i%8==3) {
					Thread.sleep(3000);
				}else if(i%32==5) {
					Thread.sleep(5000);
				}
			}
		} catch (IOException e) {
			entity.setStatus("-1");
			entity.setRemark(msg.toString());
			entity.setLastTime(new Date());
			log.error(e.getMessage());
		} catch (Exception e) {
			entity.setStatus("-1");
			entity.setRemark(msg.toString());
			entity.setLastTime(new Date());
			log.error(e.getMessage());
		}
		try {
			service.update(entity);
		} catch (Exception e1) {
			log.error("小说爬虫线程异常  " + e1.getMessage());
		}
		finally {
			try {
				Thread.sleep(60000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 创建文件
	 * 
	 * @param fileName
	 * @return
	 */
	public static void createFile(File fileName) throws Exception {
		try {
			if (!fileName.exists()) {
				fileName.createNewFile();
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		}

	}

	public static void writeTxtFile(String content, File fileName) throws Exception {
		RandomAccessFile randomFile = null;
		try {
			// 打开一个随机访问文件流，按读写方式
			randomFile = new RandomAccessFile(fileName, "rw");
			// 文件长度，字节数
			long fileLength = randomFile.length();
			// 将写文件指针移到文件尾。
			randomFile.seek(fileLength);
			String cont = content + "\r\n";
			randomFile.write(cont.getBytes("UTF-8"));
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			if (randomFile != null) {
				randomFile.close();
			}
		}
	}

	public static String FileterHtml(String str) {
		return str.replaceAll(" ", "").replaceAll("<br>", "\r\n").replaceAll("<p>", "\r\n").replaceAll("</p>", "\r\n");
	}
	
	/**
	 * <功能> 
	 * <详细描述> 
	 * @param msg
	 * @param url
	 * @param entity
	 * @param PATH
	 * @return
	 * @throws Exception 
	 * @see [类、类#方法、类#成员]
	 */
	private static int downLoad(StringBuilder msg, String url,NovelCrawEntity entity, String PATH) throws Exception{

		msg.append(url).append(",下载失败。");
		Document document2 = null;
		try {
			document2 = Jsoup.connect(url).timeout(6000).get();
		} catch (IOException e) {
			//访问失败
			return -2;
		}
		String title = "";
		String content = "";
		//        title = document2.select("h1").toString();
//        title = document2.select(".article-title").html();
		// 取标题
		if ("0".equals(entity.getTabClass())) {
			// 标题没样式，内容div有id : content
//        	title = document2.select("h1").toString();
//        	content = document2.select("#content").html();
			title  = document2.select(entity.getTitleLab()).toString();
			content = document2.select(entity.getContentLab()).html();
		} else if ("1".equals(entity.getTabClass())) {
			// 有标题样式 class
			title = document2.select(entity.getTitleLab()).html();
			content = document2.select(entity.getContentLab()).html();
		} else if ("3".equals(entity.getTabClass())) {
			// 标题没样式，内容div也没有id
			title = document2.select("h1").toString();
			content = document2.select("#content").html();
		}
//        content = document2.select(".article-content").html();
//        content = document2.select(entity.getContentLab()).html();
		log.info("线程:" + currentThread().getName() + "爬取URL—>" + url);
		//
//        String titleLab = this.entity.getTitleLab();
		title = title.replaceAll("[a-zA-Z]", "").replaceAll("<", "").replaceAll(">", "").replaceAll("\"", "")
				.replaceAll("=", "").replaceAll("-", "").replaceAll("/", "");
		title = title.trim();
		File file = new File(PATH + title + ".txt");
//        File file = new File(PATH+title.replaceAll("<h1>", "").replaceAll("</h1>", "")+".txt");
		if("".equals(title)) {
			entity.setStatus("-1");
			entity.setRemark(msg.toString());
			entity.setLastTime(new Date());
			service.update(entity);
			return -1;
		}
		createFile(file);
		log.info("创建文件:" + file.getPath());
		writeTxtFile(FileterHtml(content), file);
		File fileDir = new File(PATH + "file_dir.txt");
		createFile(fileDir);
		log.info("创建文件:" + fileDir.getPath());
		writeTxtFile(title.replace(entity.getTitle(), "").replace("《", "").replace("》", "") + ";", fileDir);
		Thread.sleep(1000);
		/// 下载 完成
		entity.setStatus("4");
		entity.setLastTime(new Date());
		return 0;
	}

}
